'''
Author: WuFeng <763467339@qq.com>
Date: 2024-11-15 17:11:08
LastEditTime: 2025-03-14 19:14:40
LastEditors: WuFeng <763467339@qq.com>
Description: web 服务器
FilePath: \markdown-magic\python\webApp.py
Copyright 版权声明

安装依赖： pip install -r requirements.txt

运行： python webApp.py

打包exe使用： pyinstaller -w -F -i icon.ico webApp.py

'''
from flask import Flask, request, jsonify, send_file, make_response
from flask_cors import CORS

from config.system import TEMP_FOLDER

from service.common import create_folder_if_not_exists
from service.pdfToDocx import convert_pdf_to_word

from service.imgToText import convert_img_to_text
from service.pdfCompress import compress_pdf_file

from service.pdfToImg import pdf_to_images

from service.pdfWatermark import create_watermark, add_watermark

from service.pdfPassword import remove_pdf_password, set_pdf_password, is_pdf_encrypted

from service.idCardOCR import idCardOCR

import functools

app = Flask(__name__)
CORS(app, supports_credentials=True, expose_headers=["Content-Disposition"])

# 全局拦截器 - 在请求处理之前执行的函数
@app.before_request
def before_request():
    # # 在这里可以进行一些全局的处理，比如设置请求头
    print("-------------------------Before request")
    # 如果 temp 文件夹不存在，就创建一个空文件夹
    create_folder_if_not_exists(TEMP_FOLDER)

# 全局拦截器 - 在请求处理之后执行的函数
@app.after_request
def after_request(response):
    print("-------------------------After request")
    return response

# 自定义切面 - 校验文件
def check_file(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # 在这里可以进行一些处理，比如验证参数
        print("-----------------+++++++++++++++++++++++++--------Before func")
        
        # 检查是否有文件在请求中
        if 'file' not in request.files:
            return jsonify({
                        'code': '201', 
                        'msg': '无file参数',
                        'data': ''
                      })
        file = request.files.get('file')
        # 如果用户没有选择文件，浏览器也会提交一个没有文件名的空部分
        if file.filename == '':
            return jsonify({
                        'code': '201', 
                        'msg': '未选择文件',
                        'data': ''
                      })
        # 调用原始的路由处理函数
        response = func(*args, **kwargs)
        print("-------------++++++++++++++++++++++++------------After func")
        return response
    return wrapper


# 主路由
@app.route('/')
def route_home():
    return('hello world!')

# 获取pdf信息
@app.route('/getPdfInfo', methods=['POST'])
@check_file
def route_getPdfInfo():
  return jsonify({
              'code': '200',
              'msg': '获取成功',
              'data': {}
            })

@app.route('/pdfToWord', methods=['POST'])
@check_file
def route_pdfToWord():
    # id = request.args.get(key='id', default='', type=str)
    # print(f"id={id}")

    # # 获取json数据
    # data = request.get_json()
    # print(f"data={data}")

    # # 获取form数据
    # file = request.form.get('file')
    # print(f"file={file}")

    # # 获取请求头数据
    # headers = request.headers
    # print(f"headers={headers}")
    # # 获取请求体数据
    # body = request.get_data()
    # print(f"body={body}")

    file = request.files.get('file')

    filePath = TEMP_FOLDER
    sourceFile = filePath + file.filename
    file.save(sourceFile)

    if is_pdf_encrypted(sourceFile) == True:
      return jsonify({
                  'code': '201',
                  'msg': 'pdf有密码保护',
                  'data': ''
                })

    processedFile = filePath + file.filename + '.docx'
    proRes = convert_pdf_to_word(sourceFile, processedFile)
    if proRes == True:
      # 返回文件给前端
      return send_file(processedFile, as_attachment=True)
      # # 创建响应对象
      # response = make_response(send_file(processedFile, as_attachment=True))
      # # 设置 Content-Disposition 响应头
      # response.headers["Content-Disposition"] = "attachment; filename=example.docx"
      # # 可选：设置 Content-Type 响应头
      # response.headers["Content-Type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
      # return response
    else:
      return jsonify({
                  'code': '201',
                  'msg': '转换失败',
                  'data': ''
                })

# 图片转文字
@app.route('/imgToText', methods=['POST'])
@check_file
def route_imgToText():
    file = request.files.get('file')

    filePath = TEMP_FOLDER
    sourceFile = filePath + file.filename
    file.save(sourceFile)
    text = convert_img_to_text(sourceFile)
    return jsonify({
                'code': '200', 
                'msg': '转换完成',
                'data': text
              })


# pdf 压缩
@app.route('/pdfCompress', methods=['POST'])
@check_file
def route_pdfCompress():
  file = request.files.get('file')

  filePath = TEMP_FOLDER
  sourceFile = filePath + file.filename
  file.save(sourceFile)

  if is_pdf_encrypted(sourceFile) == True:
    return jsonify({
                'code': '201',
                'msg': 'pdf有密码保护',
                'data': ''
              })

  outputFile = sourceFile + '.compress.pdf'
  compress_pdf_file(sourceFile, outputFile)
  return send_file(outputFile, as_attachment=True)


# pdf 转图片
@app.route('/pdfToImg', methods=['POST'])
@check_file
def route_pdfToImg():
  file = request.files.get('file')

  filePath = TEMP_FOLDER
  sourceFile = filePath + file.filename
  file.save(sourceFile)

  if is_pdf_encrypted(sourceFile) == True:
    return jsonify({
                'code': '201',
                'msg': 'pdf有密码保护',
                'data': ''
              })

  outputFile = filePath + file.filename + '.zip'
  pdf_to_images(sourceFile, outputFile)
  return send_file(outputFile, as_attachment=True)


# pdf 加水印
@app.route('/pdfAddWatermark', methods=['POST'])
@check_file
def route_pdfAddWatermark():
  file = request.files.get('file')

  filePath = TEMP_FOLDER
  sourceFile = filePath + file.filename
  file.save(sourceFile)

  if is_pdf_encrypted(sourceFile) == True:
    return jsonify({
                'code': '201',
                'msg': 'pdf有密码保护，无法加水印',
                'data': ''
              })

  watermark_pdf = filePath + file.filename + '.watermark.pdf'

  # 创建水印 PDF 文件
  create_watermark("牛a儿b还c在山坡吃草", watermark_pdf, '米芾字体')

  # 将水印添加到 PDF 文件
  output_pdf = filePath + file.filename + '.watermark.output.pdf'
  add_watermark(sourceFile, output_pdf, watermark_pdf)
  return send_file(output_pdf, as_attachment=True)


# pdf 解锁
@app.route('/removePdfPassword', methods=['POST'])
@check_file
def route_removePdfPassword():
  file = request.files.get('file')
  password = request.form.get('password')

  filePath = TEMP_FOLDER
  sourceFile = filePath + file.filename
  file.save(sourceFile)

  output_pdf = filePath + file.filename + '.removePdfPassword.output.pdf'
  removeResult = remove_pdf_password(sourceFile, output_pdf, password)
  if removeResult == 'noPassword':
    return jsonify({
                'code': '201',
                'msg': '文件无密码',
                'data': ''
              })
  elif removeResult == 'passwordError':
    return jsonify({
                'code': '201',
                'msg': '密码错误',
                'data': ''
              })
  else:
    return send_file(output_pdf, as_attachment=True)


# pdf 设置密码
@app.route('/setPdfPassword', methods=['POST'])
@check_file
def route_setPdfPassword():
  file = request.files.get('file')
  userPassword = request.form.get(key='userPassword', default='', type=str)
  ownerPassword = request.form.get(key='ownerPassword', default='', type=str)
  if userPassword == '' or ownerPassword == '':
    return jsonify({
                'code': '201',
                'msg': '密码不能为空',
                'data': ''
              })

  filePath = TEMP_FOLDER
  sourceFile = filePath + file.filename
  file.save(sourceFile)

  output_pdf = filePath + file.filename + '.setPdfPassword.output.pdf'
  set_pdf_password(sourceFile, output_pdf, userPassword, ownerPassword)
  return send_file(output_pdf, as_attachment=True)



# 图片转文字
@app.route('/idCardOCR', methods=['POST'])
@check_file
def route_idCardOCR():
    file = request.files.get('file')

    filePath = TEMP_FOLDER
    sourceFile = filePath + file.filename
    file.save(sourceFile)
    text = idCardOCR(sourceFile)
    return jsonify({
                'code': '200', 
                'msg': '转换完成',
                'data': text
              })


if __name__ == '__main__':
    app.run(debug=True, port=19999)